using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using DesktopHelper.Services;

namespace DesktopHelper.Views
{
    public partial class ScreenshotEditWindow : Window
    {
        private readonly ScreenshotService _screenshotService;
        private readonly PinnedImageService _pinnedImageService;
        
        private Bitmap _originalBitmap;
        private Bitmap _editedBitmap;
        private DrawingTool _currentTool = DrawingTool.None;
        private System.Windows.Media.Brush _currentBrush = System.Windows.Media.Brushes.Black;
        private double _currentThickness = 2;
        
        private bool _isDrawing = false;
        private System.Windows.Point _startPoint;
        private UIElement? _currentDrawingElement;
        
        private Stack<UIElement> _undoStack = new();
        private Stack<UIElement> _redoStack = new();
        
        public enum DrawingTool
        {
            None,
            Pen,
            Rectangle,
            Circle,
            Arrow,
            Text
        }

        public ScreenshotEditWindow(Bitmap screenshot)
        {
            InitializeComponent();
            
            // 获取服务
            var app = (App)System.Windows.Application.Current;
            _screenshotService = app.Host?.Services.GetRequiredService<ScreenshotService>() 
                               ?? throw new InvalidOperationException("无法获取截图服务");
            _pinnedImageService = app.Host?.Services.GetRequiredService<PinnedImageService>() 
                                ?? throw new InvalidOperationException("无法获取钉图服务");
            
            _originalBitmap = screenshot;
            _editedBitmap = new Bitmap(screenshot);
            
            InitializeWindow();
            LoadScreenshot();
        }

        private void InitializeWindow()
        {
            // 设置窗口大小和位置
            var screenWidth = SystemParameters.PrimaryScreenWidth;
            var screenHeight = SystemParameters.PrimaryScreenHeight;
            
            Width = Math.Min(_originalBitmap.Width + 100, screenWidth * 0.9);
            Height = Math.Min(_originalBitmap.Height + 150, screenHeight * 0.9);
            
            // 居中显示
            Left = (screenWidth - Width) / 2;
            Top = (screenHeight - Height) / 2;
            
            // 设置默认颜色
            ColorPicker.SelectedIndex = 4; // 黑色
        }

        private void LoadScreenshot()
        {
            // 将Bitmap转换为BitmapSource
            var bitmapSource = BitmapToBitmapSource(_originalBitmap);
            ScreenshotImage.Source = bitmapSource;
            
            // 设置Canvas大小
            EditCanvas.Width = _originalBitmap.Width;
            EditCanvas.Height = _originalBitmap.Height;
            DrawingLayer.Width = _originalBitmap.Width;
            DrawingLayer.Height = _originalBitmap.Height;
        }

        private BitmapSource BitmapToBitmapSource(Bitmap bitmap)
        {
            using var memory = new MemoryStream();
            bitmap.Save(memory, ImageFormat.Png);
            memory.Position = 0;
            
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = memory;
            bitmapImage.EndInit();
            bitmapImage.Freeze();
            
            return bitmapImage;
        }

        #region 工具选择事件
        private void PenTool_Click(object sender, RoutedEventArgs e)
        {
            SelectTool(DrawingTool.Pen, PenTool);
        }

        private void RectangleTool_Click(object sender, RoutedEventArgs e)
        {
            SelectTool(DrawingTool.Rectangle, RectangleTool);
        }

        private void CircleTool_Click(object sender, RoutedEventArgs e)
        {
            SelectTool(DrawingTool.Circle, CircleTool);
        }

        private void ArrowTool_Click(object sender, RoutedEventArgs e)
        {
            SelectTool(DrawingTool.Arrow, ArrowTool);
        }

        private void TextTool_Click(object sender, RoutedEventArgs e)
        {
            SelectTool(DrawingTool.Text, TextTool);
        }

        private void SelectTool(DrawingTool tool, ToggleButton button)
        {
            // 取消其他工具的选中状态
            PenTool.IsChecked = false;
            RectangleTool.IsChecked = false;
            CircleTool.IsChecked = false;
            ArrowTool.IsChecked = false;
            TextTool.IsChecked = false;
            
            // 设置当前工具
            _currentTool = tool;
            button.IsChecked = true;
            
            Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 选择工具: {tool}");
        }
        #endregion

        #region 属性设置事件
        private void ColorPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (ColorPicker.SelectedItem is ComboBoxItem item)
            {
                _currentBrush = item.Background;
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 选择颜色: {item.Content}");
            }
        }

        private void ThicknessSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            _currentThickness = e.NewValue;
            Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 设置线条粗细: {_currentThickness}");
        }
        #endregion

        #region 绘制事件
        private void EditCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (_currentTool == DrawingTool.None) return;
            
            _isDrawing = true;
            _startPoint = e.GetPosition(DrawingLayer);
            EditCanvas.CaptureMouse();
            
            if (_currentTool == DrawingTool.Text)
            {
                AddTextBox(_startPoint);
            }
            else if (_currentTool == DrawingTool.Pen)
            {
                StartDrawingPath(_startPoint);
            }
            else
            {
                // 矩形、圆形、箭头等形状工具
                _currentDrawingElement = CreateShapeElement(_currentTool);
                if (_currentDrawingElement != null)
                {
                    DrawingLayer.Children.Add(_currentDrawingElement);
                }
            }
        }

        private void EditCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_isDrawing || _currentTool == DrawingTool.None) return;
            
            var currentPoint = e.GetPosition(DrawingLayer);
            
            if (_currentTool == DrawingTool.Pen && _currentDrawingElement is Polyline polyline)
            {
                polyline.Points.Add(currentPoint);
            }
            else if (_currentDrawingElement != null)
            {
                UpdateShapeElement(_currentDrawingElement, _startPoint, currentPoint);
            }
        }

        private void EditCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!_isDrawing) return;
            
            _isDrawing = false;
            EditCanvas.ReleaseMouseCapture();
            
            if (_currentDrawingElement != null)
            {
                _undoStack.Push(_currentDrawingElement);
                _redoStack.Clear();
                _currentDrawingElement = null;
                
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 完成绘制");
            }
        }

        private void StartDrawingPath(System.Windows.Point startPoint)
        {
            var polyline = new Polyline
            {
                Stroke = _currentBrush,
                StrokeThickness = _currentThickness,
                StrokeLineJoin = PenLineJoin.Round,
                StrokeStartLineCap = PenLineCap.Round,
                StrokeEndLineCap = PenLineCap.Round
            };
            polyline.Points.Add(startPoint);
            
            _currentDrawingElement = polyline;
            DrawingLayer.Children.Add(polyline);
        }

        private UIElement CreateShapeElement(DrawingTool tool)
        {
            return tool switch
            {
                DrawingTool.Rectangle => new System.Windows.Shapes.Rectangle
                {
                    Stroke = _currentBrush,
                    StrokeThickness = _currentThickness,
                    Fill = System.Windows.Media.Brushes.Transparent
                },
                DrawingTool.Circle => new Ellipse
                {
                    Stroke = _currentBrush,
                    StrokeThickness = _currentThickness,
                    Fill = System.Windows.Media.Brushes.Transparent
                },
                DrawingTool.Arrow => new Line
                {
                    Stroke = _currentBrush,
                    StrokeThickness = _currentThickness,
                    StrokeStartLineCap = PenLineCap.Round,
                    StrokeEndLineCap = PenLineCap.Triangle
                },
                _ => null
            };
        }

        private void UpdateShapeElement(UIElement element, System.Windows.Point start, System.Windows.Point current)
        {
            switch (element)
            {
                case System.Windows.Shapes.Rectangle rect:
                    var rectWidth = Math.Abs(current.X - start.X);
                    var rectHeight = Math.Abs(current.Y - start.Y);
                    Canvas.SetLeft(rect, Math.Min(start.X, current.X));
                    Canvas.SetTop(rect, Math.Min(start.Y, current.Y));
                    rect.Width = rectWidth;
                    rect.Height = rectHeight;
                    break;
                    
                case Ellipse ellipse:
                    var ellipseWidth = Math.Abs(current.X - start.X);
                    var ellipseHeight = Math.Abs(current.Y - start.Y);
                    Canvas.SetLeft(ellipse, Math.Min(start.X, current.X));
                    Canvas.SetTop(ellipse, Math.Min(start.Y, current.Y));
                    ellipse.Width = ellipseWidth;
                    ellipse.Height = ellipseHeight;
                    break;
                    
                case Line line:
                    line.X1 = start.X;
                    line.Y1 = start.Y;
                    line.X2 = current.X;
                    line.Y2 = current.Y;
                    break;
            }
        }

        private void AddTextBox(System.Windows.Point position)
        {
            var textBox = new TextBox
            {
                Background = System.Windows.Media.Brushes.Transparent,
                BorderThickness = new Thickness(1),
                BorderBrush = _currentBrush,
                Foreground = _currentBrush,
                FontSize = 14,
                MinWidth = 100,
                Text = "输入文字"
            };
            
            Canvas.SetLeft(textBox, position.X);
            Canvas.SetTop(textBox, position.Y);
            
            DrawingLayer.Children.Add(textBox);
            textBox.Focus();
            textBox.SelectAll();
            
            _undoStack.Push(textBox);
            _redoStack.Clear();
        }
        #endregion

        #region 撤销重做
        private void UndoButton_Click(object sender, RoutedEventArgs e)
        {
            if (_undoStack.Count > 0)
            {
                var element = _undoStack.Pop();
                DrawingLayer.Children.Remove(element);
                _redoStack.Push(element);
                
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 撤销操作");
            }
        }

        private void RedoButton_Click(object sender, RoutedEventArgs e)
        {
            if (_redoStack.Count > 0)
            {
                var element = _redoStack.Pop();
                DrawingLayer.Children.Add(element);
                _undoStack.Push(element);
                
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 重做操作");
            }
        }
        #endregion

        #region 按钮事件
        private void CopyToClipboardButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var editedBitmap = CreateFinalBitmap();
                var bitmapSource = BitmapToBitmapSource(editedBitmap);
                Clipboard.SetImage(bitmapSource);
                
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 图片已复制到剪贴板");
                MessageBox.Show("图片已复制到剪贴板！", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 复制到剪贴板失败: {ex.Message}");
                MessageBox.Show($"复制失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void SaveImageButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var editedBitmap = CreateFinalBitmap();
                var filePath = _screenshotService.SaveScreenshot(editedBitmap);
                
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 图片已保存: {filePath}");
                MessageBox.Show($"图片已保存到:\n{filePath}", "保存成功", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 保存图片失败: {ex.Message}");
                MessageBox.Show($"保存失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void PinImageButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var editedBitmap = CreateFinalBitmap();
                var filePath = _screenshotService.SaveScreenshot(editedBitmap);
                _pinnedImageService.PinImageToDesktop(filePath);
                
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 图片已钉到桌面");
                MessageBox.Show("图片已钉到桌面！", "钉图成功", MessageBoxButton.OK, MessageBoxImage.Information);
                Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 钉图失败: {ex.Message}");
                MessageBox.Show($"钉图失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                Close();
            }
        }
        #endregion

        private Bitmap CreateFinalBitmap()
        {
            // 创建最终的合成图片
            var finalBitmap = new Bitmap(_originalBitmap.Width, _originalBitmap.Height);
            
            using (var graphics = Graphics.FromImage(finalBitmap))
            {
                // 绘制原始图片
                graphics.DrawImage(_originalBitmap, 0, 0);
                
                // 将WPF Canvas渲染到位图
                var renderBitmap = new RenderTargetBitmap(
                    _originalBitmap.Width, _originalBitmap.Height, 96, 96, PixelFormats.Pbgra32);
                renderBitmap.Render(DrawingLayer);
                
                // 转换并合并
                var encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
                
                using var stream = new MemoryStream();
                encoder.Save(stream);
                stream.Position = 0;
                
                using var overlayBitmap = new Bitmap(stream);
                graphics.DrawImage(overlayBitmap, 0, 0);
            }
            
            return finalBitmap;
        }

        protected override void OnClosed(EventArgs e)
        {
            _originalBitmap?.Dispose();
            _editedBitmap?.Dispose();
            base.OnClosed(e);
        }
    }
}